package team.scau.laboratory_repair.service;

import com.querydsl.core.QueryResults;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.jpa.impl.JPAQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import team.scau.laboratory_repair.common.base.BaseService;
import team.scau.laboratory_repair.common.constant.ConstantRole;
import team.scau.laboratory_repair.common.enums.WechatUserType;
import team.scau.laboratory_repair.common.page.MyPage;
import team.scau.laboratory_repair.common.utils.Md5Utils;
import team.scau.laboratory_repair.modules.po.QUser;
import team.scau.laboratory_repair.modules.po.User;
import team.scau.laboratory_repair.modules.po.WechatUser;
import team.scau.laboratory_repair.modules.repository.UserRepository;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 30254
 * creadtedate:2018/8/19
 */
@Service
public class UserService extends BaseService<User, UserRepository> {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private WechatUserService wechatUserService;

    private QUser qUser = QUser.user;

    @Override
    public UserRepository getRepository() {
        return userRepository;
    }

    @Override
    public EntityPathBase<User> getQBase() {
        return qUser;
    }

    public QueryResults<User> listOrByExample(User user, MyPage page) {
        JPAQuery<User> jpaQuery = queryFactory.select(qUser).from(qUser);
        if (user != null) {
            if (StringUtils.isNotBlank(user.getUsername())){
                jpaQuery = jpaQuery.where(qUser.username.eq(user.getUsername()));
            }
            if (user.getRole()!=null){
                jpaQuery = jpaQuery.where(qUser.role.eq(user.getRole()));
            }
            if (StringUtils.isNotBlank(user.getAccount())) {
                jpaQuery = jpaQuery.where(qUser.account.eq(user.getAccount()));
            }
        }
        jpaQuery = jpaQuery.where(qUser.valid.eq(true))
                .where(qUser.id.ne(1L));
        if (page != null) {
            jpaQuery = jpaQuery.orderBy(page.getSort()).offset(page.getPage()).limit(page.getSize());
        }
        return jpaQuery.fetchResults();

    }

    public User getByAccount(String account) throws Exception {
        JPAQuery<User> jpaQuery = queryFactory.select(qUser).from(qUser);
        if (StringUtils.isNotBlank(account)) {
            jpaQuery = jpaQuery.where(qUser.account.eq(account));
        }
        jpaQuery = jpaQuery.where(qUser.valid.eq(true));
        return jpaQuery.fetchOne();

//        return userRepository.findOne((Specification<User>) (root, query, cb) -> {
//            Predicate predicate = cb.conjunction();
//            List<Expression<Boolean>> expressions = predicate.getExpressions();
//            expressions.add(cb.equal(root.get("valid"), 1));
//            if (StringUtils.isNotBlank(account)) {
//                expressions.add(cb.equal(root.get("account"), account));
//            }
//            return predicate;
//        }).orElse(null);
    }

    public User getByPhoneNumber(String phoneNumber) throws Exception {
        JPAQuery<User> jpaQuery = queryFactory.select(qUser).from(qUser);
        if (StringUtils.isNotBlank(phoneNumber)) {
            jpaQuery = jpaQuery.where(qUser.phoneNumber.eq(phoneNumber));
        }
        jpaQuery = jpaQuery.where(qUser.valid.eq(true));
        return jpaQuery.fetchOne();

    }

    public List<User> listAllStaff() throws Exception {
        JPAQuery<User> jpaQuery = queryFactory.select(qUser).from(qUser)
                .where(qUser.role.eq(ConstantRole.ROLE_STAFF))
                .where(qUser.valid.eq(true));
        return jpaQuery.fetch();
    }

    public List<User> listAllManager() throws Exception {
        JPAQuery<User> jpaQuery = queryFactory.select(qUser).from(qUser)
                .where(qUser.role.eq(ConstantRole.ROLE_MANAGER))
                .where(qUser.valid.eq(true));
        return jpaQuery.fetch();
    }

    public List<User> listByIds(List<Long> ids){
        if(ids == null || ids.size() == 0){
            return new ArrayList<>();
        }
        JPAQuery<User> jpaQuery = queryFactory.select(qUser).from(qUser)
                .where(qUser.id.in(ids))
                .where(qUser.valid.eq(true));
        return jpaQuery.fetch();
    }

    @Override
    public void save(User user) throws Exception {
        user.setPassword(new Md5Utils().getkeyBeanofStr(user.getPassword()).toUpperCase());
        super.save(user);
        WechatUser wechatUser = WechatUser.builder().name(user.getUsername()).nickname(user.getUsername())
                .password(user.getPassword()).subscribe(false).userId(user.getId())
                .phoneNumber(user.getPhoneNumber()).build();
        if(user.getRole().equals(ConstantRole.ROLE_STAFF)){
            wechatUser.setUserType(WechatUserType.STAFF.getType());
        }
        else if(user.getRole().equals(ConstantRole.ROLE_MANAGER)){
            wechatUser.setUserType(WechatUserType.LEADER.getType());
        }
        wechatUserService.save(wechatUser);
    }

    public void updatePw(User user, String oldPw, String newPw, String repeatPw) throws Exception {
        if (!newPw.equals(repeatPw)) {
            throw new RuntimeException("两次输入的新密码不同");
        }
        if (!user.getPassword().equalsIgnoreCase(new Md5Utils().getkeyBeanofStr(oldPw).toUpperCase())) {
            throw new RuntimeException("旧密码不正确");
        } else if (user.getPassword().equalsIgnoreCase(new Md5Utils().getkeyBeanofStr(newPw).toUpperCase())) {
            throw new RuntimeException("新密码不能与旧密码相同");
        } else {
            user.setPassword(new Md5Utils().getkeyBeanofStr(newPw).toUpperCase());
            super.save(user);
        }
    }

}
